//
// Created by china on 25-1-4.
//

//业务逻辑

#ifndef CHAT_CHATSERVICE_H
#define CHAT_CHATSERVICE_H

#include <muduo/net/TcpServer.h>
#include <muduo/net/EventLoop.h>
#include <muduo/base/Logging.h>
#include <json.hpp>
#include <unordered_map>
#include <functional>
#include <mutex>
#include <vector>
#include "DataBase.hpp"
#include "UserModel.h"
#include "OfflineMessageModel.h"
#include "FriendModel.h"
#include "GroupModel.h"
#include "Redis.h"

using namespace muduo;
using namespace muduo::net;
using namespace std::placeholders;

using MsgHandler = std::function<void(const TcpConnectionPtr& conn,nlohmann::json &js,Timestamp time)>;

class ChatService {
public:
    //获取单例
    static ChatService* getInstance();
    //处理登录业务
    void logic(const TcpConnectionPtr& conn,nlohmann::json &js,Timestamp time);
    //处理注册业务
    void regist(const TcpConnectionPtr& conn,nlohmann::json &js,Timestamp time);
    //处理私聊业务
    void oneChat(const TcpConnectionPtr& conn,nlohmann::json &js,Timestamp time);
    //处理添加好友业务
    void addFriend(const TcpConnectionPtr& conn,nlohmann::json &js,Timestamp time);
    //处理创建群业务
    void creatGroup(const TcpConnectionPtr& conn,nlohmann::json &js,Timestamp time);
    //处理添加群业务
    void addGroup(const TcpConnectionPtr& conn,nlohmann::json &js,Timestamp time);
    //处理群聊天业务
    void groupChat(const TcpConnectionPtr& conn,nlohmann::json &js,Timestamp time);
    //获取离线消息
    std::vector<std::string> getOfflineMsg(const struct MySQLTable::User& user);
    //获取好友关系
    std::vector<std::string> getFriends(const struct MySQLTable::User& user);
    //获取群聊消息
    std::vector<std::string> getGroupMsg(const struct MySQLTable::User& user);
    //处理 redis 订阅
    void handleRedisSubscribeMessage(int,std::string);
    //处理客户端退出业务
    void clientCloseExcption(const TcpConnectionPtr& conn);
    //处理服务器退出事件
    void reset();
    //获取消息对应的处理器
    MsgHandler getHandler(const ReqType&);
private:
    //采取单例模式
    ChatService();
    //存储消息id和对应业务的处理方法，通过id区分不同的业务
    std::unordered_map<ReqType,MsgHandler> _msgHandlerMap;
    //用户id与连接的映射，由于该映射很多地方用，注意线程安全
    std::unordered_map<int,TcpConnectionPtr> _userConnMap;
    //建立锁，保证 _userConnMap 的线程安全
    std::mutex _connMutex;
    //User 表操作对象
    UserModel _userModel;
    OfflineMessageModel _offlineMessageModel;
    FriendModel _addFriendModel;
    GroupModel _groupModel;
    Redis _redis;
};


#endif //CHAT_CHATSERVICE_H
